﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace 分片上传.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class FileController : Controller
    {
        [HttpGet("test")]
        public IActionResult test()
        {
            return Ok(new { msg = "success", code = 200, data =""});
        }

        [HttpPost("MergeChunkFile")]
        public IActionResult MergeChunkFile( [FromBody] MergeFileDto dto)
        {
           
            var result = MergeFile(dto);
            return Ok(new { result = dto.FileMd5 });
        }

        private  bool MergeFile(MergeFileDto dto)
        {
            var fileID = dto.FileMd5;
            var filepath = CreateFilePath($"Documents/{fileID}");
            var filesList =   Directory.GetFiles(filepath);
            var fullpath = filepath + "/" + dto.FileName;

            using (FileStream outPutFile = new FileStream(fullpath, FileMode.OpenOrCreate, FileAccess.Write))
            {
                for (int i = 0; i < filesList.Count(); i++)
                {
                    using (FileStream inputTempFile = new FileStream(filesList[i], FileMode.OpenOrCreate, FileAccess.Read))
                    {
                        int bytesRead = 0;
                        byte[] buffer = new byte[1024*1024*5];
                        while ((bytesRead = inputTempFile.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            outPutFile.Write(buffer, 0, bytesRead);
                        }
                       
                    }
                    System.IO.File.Delete(filesList[i]);
                }
            }

            return true;
        }


        [DisableRequestSizeLimit]
        [HttpPost("ChunkUpload")]
        public IActionResult ChunkUpload([FromForm] Microsoft.AspNetCore.Http.IFormCollection form)
        {
            if (Request.Form.Files.Count < 1)
            {
                return Ok(new ApiResult(-1,"未选择文件",null) );
            }
            foreach (var item in form.Keys)
            {
                Console.WriteLine( $"key:{item},value:{form[item].ToString()}");
            }
            Console.WriteLine(form.Files[0].FileName);
            var md5 = form["md5value"].ToString();
            var name = form["Name"].ToString();
            var type = form["Type"].ToString();
            var lastModifiedDate = form["LastModifiedDate"].ToString();
            var size = Convert.ToInt64(form["Size"]);
            var chunks = form["Chunks"].ToString();
            Console.WriteLine($"chunks:{chunks}");
            var chunk = form["Chunk"].ToString();
            Console.WriteLine($"chunk:{chunk}");
            var isChunk = Convert.ToBoolean(form["IsChunked"]);
            Console.WriteLine($"chunk:{isChunk}");
            var file = form.Files[0];

            //分片
            if (isChunk)
            {
                Console.WriteLine("分片");
                using var stream = file.OpenReadStream();
                byte[] buffer = new byte[stream.Length];
                stream.Read(buffer, 0, buffer.Length);
                ChunkUpload(md5, name.Replace(" ", ""), size, Convert.ToInt32(chunks), Convert.ToInt32(chunk), buffer);
                return Ok( new ApiResult(0, "success", DateTime.Now));
            }
            //非分片
            else
            {
                Console.WriteLine("非分片");
                using var stream = file.OpenReadStream();
                byte[] buffer = new byte[stream.Length];
                stream.Read(buffer, 0, buffer.Length);
                UploadFiles(new List<string> { file.FileName.Replace(" ", "") }, new List<byte[]> { buffer });
                return Ok(new ApiResult(0, "success", DateTime.Now));
            }
        }
        private bool ChunkUpload(string md5, string name, long size, int chunks, int chunk, byte[] buffer)
        {
            //上传当前分片数据
            // var data = Repository.UploadFile($"{name}_Chunk_{chunk}", buffer);
         
            var path = CreateFilePath($"Documents/{md5}");
            var fullpath = path + $"/{name}_Chunk_{chunk}";
            var result = CreateFile(buffer, fullpath);
            return result;
        }

        [NonAction]
        public  bool  UploadFiles(IList<string> fileNames, IList<byte[]> fileBytes)
        {
            for (var i = 0; i < fileNames.Count; i++)
            {
                var filename = fileNames[i];

                var filetype = filename.Substring(filename.LastIndexOf("."), filename.Length - filename.LastIndexOf("."));
                var name = filename.Replace(filetype, "").Replace(" ", "");
                var _id = Guid.NewGuid().ToString().Replace("-", "");

           
                //创建目录
                var path = CreateFilePath($"Documents/{_id}");
                //创建文件
                var fullpath = path + $"/{fileNames[i]}";
                var result = CreateFile(fileBytes[i], fullpath);
            }
            return true;
        }

        private string CreateFilePath(string path)
        {
            path = AppDomain.CurrentDomain.BaseDirectory + path;
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            return path;
        }

        /// <summary>
        /// 创建文件
        /// </summary>
        /// <param name="file"></param>
        /// <param name="fullpath"></param>
        /// <returns></returns>
        private bool CreateFile(byte[] file, string fullpath)
        {
            try
            {
                using (FileStream stream = System.IO. File.Create(fullpath))
                {
                    stream.Write(file, 0, file.Length);
                    stream.Close();
                }
                return true;
            }
            catch
            {
                return false;
            }

        }
    }

    public class FileSort
    {
        public const string PART_NUMBER = ".partNumber-";
        /// <summary>
        /// 文件名
        /// </summary>
        public string FileName { get; set; }
        /// <summary>
        /// 文件分片号
        /// </summary>
        public int PartNumber { get; set; }
    }
    public   class MergeFileDto
    {
        public string FileMd5 { get; set; }
        public string FileName { get; set; }
    }
}
